
// 定义一个简单的类型别名，让代码更清晰
type CesiumLayer = Cesium.ImageryLayer | Cesium.GeoJsonDataSource | Cesium.Cesium3DTileset;

export class LayerManager {
  private viewer: Cesium.Viewer;
  // 使用 Map 存储 ID 和 Cesium 图层对象的映射
  private layerMap: Map<string, CesiumLayer>;

  constructor(viewer: Cesium.Viewer) {
    this.viewer = viewer;
    this.layerMap = new Map();
  }

  /**
   * 公共入口：加载整个图层配置数组
   * @param configData - 从文件导入的配置数组
   */
  public async loadLayersFromConfig(configData: any[]) {
    console.log('开始加载图层配置...');
    for (const node of configData) {
      await this.processNode(node);
    }
    console.log('所有图层加载任务已启动。');
  }

  /**
   * 根据 ID 获取 Cesium 图层实例
   * @param id - 图层 ID
   * @returns CesiumLayer | undefined
   */
  public getLayerById(id: string): CesiumLayer | undefined {
    return this.layerMap.get(id);
  }

  /**
   * 控制图层显隐
   * @param id - 图层 ID
   * @param show - 是否显示
   */
  public setLayerVisibility(id: string, show: boolean) {
    const layer = this.getLayerById(id);
    if (layer) {
      layer.show = show;
      console.log(`图层 ${id} 可见性设置为: ${show}`);
    } else {
      console.warn(`未找到 ID 为 ${id} 的图层`);
    }
  }

  /**
   * 销毁所有已加载的图层
   */
  public destroyAll() {
    this.layerMap.forEach((layer, id) => {
      if (layer instanceof Cesium.ImageryLayer) {
        this.viewer.imageryLayers.remove(layer);
      } else if (layer instanceof Cesium.GeoJsonDataSource) {
        this.viewer.dataSources.remove(layer);
      } else if (layer instanceof Cesium.Cesium3DTileset) {
        this.viewer.scene.primitives.remove(layer);
      }
    });
    this.layerMap.clear();
    console.log('所有受管理的图层已销毁。');
  }

  /**
   * 递归处理节点
   * @param node - 当前数据节点
   */
  private async processNode(node: any) {
    // 如果是可加载的图层节点 (type === 'Feature')
    if (node.type === 'Feature' && node.properties) {
      await this.loadFeature(node.properties);
    }

    // 如果有子节点，继续递归
    if (node.children && Array.isArray(node.children)) {
      for (const child of node.children) {
        await this.processNode(child);
      }
    }
  }

  /**
   * 根据 Feature 的 properties 加载具体图层
   * @param props - 节点的 properties 对象
   */
  private async loadFeature(props: any) {
    const { id, checked, renderingType } = props;
    if (!id || !renderingType) return;

    let cesiumLayer: CesiumLayer | undefined;

    try {
      switch (renderingType) {
        case 'imagery':
          cesiumLayer = this.loadImageryLayer(props);
          break;
        case 'geojson':
          // GeoJSON 加载是异步的
          cesiumLayer = await this.loadGeoJsonDataSource(props);
          break;
        case 'tileset':
          // 3D Tileset 加载也是异步的
          cesiumLayer = await this.loadTileset(props);
          break;
        default:
          console.warn(`未知的 renderingType: ${renderingType}`);
          return;
      }

      if (cesiumLayer) {
        cesiumLayer.show = checked;
        this.layerMap.set(id, cesiumLayer);
        console.log(`成功加载图层: ${props.name} (ID: ${id})`);
      }
    } catch (error) {
      console.error(`加载图层 ${props.name} (ID: ${id}) 失败:`, error);
    }
  }

  // --- 具体图层的加载方法 ---

  private loadImageryLayer(props: any): Cesium.ImageryLayer | undefined {
    const wmsProps = props.props?.imagery?.children?.[0]?.props;
     if (!wmsProps || !wmsProps.url || !wmsProps.layers) {
      console.error(`图层 ${props.name} 的 WMS 配置不完整 (缺少 url 或 layers)`);
      return;
    }
    const provider = new Cesium.WebMapServiceImageryProvider({
      url: wmsProps.url,
      layers: wmsProps.layers,
      parameters: wmsProps.parameters || {
        transparent: true,
        format: 'image/png'
      },
      enablePickFeatures: wmsProps.enablePickFeatures ?? true,
    });

    const imageryLayer = this.viewer.imageryLayers.addImageryProvider(provider);
    // 设置 vue-cesium 中的其他属性
    imageryLayer.alpha = props.props?.imagery?.alpha ?? 1.0;
    imageryLayer.brightness = props.props?.imagery?.brightness ?? 1.0;
    imageryLayer.contrast = props.props?.imagery?.contrast ?? 1.0;
    
    return imageryLayer;
  }

  private async loadGeoJsonDataSource(props: any): Promise<Cesium.GeoJsonDataSource | undefined> {
    const geojsonProps = props.props;
    if (!geojsonProps || !geojsonProps.data) return;
    const dataSource = await Cesium.GeoJsonDataSource.load(geojsonProps.data, {
      stroke: Cesium.Color.fromCssColorString(geojsonProps.stroke || '#FFFF00'),
      fill: Cesium.Color.fromCssColorString(geojsonProps.fill || 'rgba(255, 255, 0, 0.2)'),
      strokeWidth: geojsonProps.strokeWidth || 2,
      clampToGround: geojsonProps.clampToGround ?? false,
    });

    dataSource.name = props.name;
    await this.viewer.dataSources.add(dataSource);
    const entities = dataSource.entities.values;
    for (let i = 0; i < entities.length; i++) {
        const entity = entities[i];
        if (entity.billboard) {
            entity.billboard = undefined; // 移除默认的billboard
            entity.point = new Cesium.PointGraphics({
                color: Cesium.Color.YELLOW, // 点的填充色
                pixelSize: 10, // 点的大小（像素）
                outlineColor: Cesium.Color.BLACK, // 点的轮廓色
                outlineWidth: 1, // 轮廓宽度
            })
            entity.label = new Cesium.LabelGraphics({
                text: entity.properties.SYDWZ,
                font: '14pt sans-serif',
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                fillColor: Cesium.Color.WHITE,
                outlineColor: Cesium.Color.BLUE,
                outlineWidth: 2,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(0, -12),
                // disableDepthTestDistance: Number.POSITIVE_INFINITY,
                 distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 100000),
            });
        }
    }
    return dataSource;
  }

  private async loadTileset(props: any): Promise<Cesium.Cesium3DTileset | undefined> {
    const tilesetProps = props.props?.tileset;
    if (!tilesetProps || !tilesetProps.url) return;

    // modelMatrix 需要从数组转换为 Cesium.Matrix4
    const modelMatrix = tilesetProps.modelMatrix 
      ? Cesium.Matrix4.fromArray(tilesetProps.modelMatrix) 
      : Cesium.Matrix4.IDENTITY;

    const tileset = await Cesium.Cesium3DTileset.fromUrl(tilesetProps.url, {
      modelMatrix: modelMatrix,
      // 其他可能的 3D Tileset 选项
      // maximumScreenSpaceError: 16,
    });

    this.viewer.scene.primitives.add(tileset);
    return tileset;
  }
}
